using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Collections.Specialized;
using System.Collections.Generic;

namespace LogFileViewer
{
    public partial class MainWindow : Form
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void benchmark()
        {
            //System.Diagnostics.Process proc = new System.Diagnostics.Process();
            //proc.PagedMemorySize64;
            //proc.PagedSystemMemorySize64;
            //proc.PrivilegedProcessorTime;
            //proc.TotalProcessorTime;
            //proc.UserProcessorTime;
            //proc.VirtualMemorySize64;

            System.Diagnostics.PerformanceCounter myCounter;
            myCounter = new System.Diagnostics.PerformanceCounter();

            myCounter.CategoryName = "Processor";
            myCounter.CounterName = "% Processor Time";
            myCounter.InstanceName = "_Total";

            for (int i = 0; i < 20; i++)
                myCounter.NextValue();

        }

        private static Properties.Settings sets = Properties.Settings.Default;

        /// <summary>
        ///     This one stores all or data for several message types.
        /// </summary>
        private Dictionary<MessageTypes, List<LogEntry>> data;

        private DataAccess dataAccess;

        private List<LogEntry> getData(string type)
        {
            if (type != null && this.data != null)
            {
                MessageTypes msgType = MessageType.GetMessageType(type);
                if (this.data.ContainsKey(msgType))
                {
                    return this.data[msgType];
                }
            }
            return null;
        }

        private List<LogEntry> getData(int typeIndex)
        {
            if (this.data != null)
            {
                MessageTypes msgType = MessageType.MessageTypeAt(typeIndex);
                if (this.data.ContainsKey(msgType))
                {
                    return this.data[msgType];
                }
            }
            return null;
        }

        // Currently this is not supported because values are always overwritten
        private void OpenSeveralLogfiles(string[] loadThis)
        {
            for (int i = 0; i < loadThis.Length; i++)
            {
                //OpenLogfile(loadThis[i]);
            }
        }

        /// <summary>
        ///     Calculates the dividor that's needed for progress bar to bar
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public double getProgressBarDividor(FileStream str)
        {
            //  Calculate maximum and divider for progress bar
            double dividor = 0;
            Int32 max = 0;
            long value = str.Length;
            if (value > Int32.MaxValue)
            {
                dividor = (double)value / Int32.MaxValue;
                max = Int32.MaxValue;
            }
            else
            {
                max = (int)value;
            }
            loadFileProgressBar.Maximum = max;
            return dividor;
        }

        /// <summary>
        ///     Increments progress bar to the specified value.
        /// </summary>
        /// <param name="dividor"></param>
        /// <param name="position"></param>
        public void incrementProgressBar(double dividor, long position)
        {
            // update progress bar
            int realnumber = (int)position;
            if (dividor != 0)
            {
                // Number is bigger than integer
                realnumber = (int)(position / dividor);
            }
            loadFileProgressBar.Value = realnumber;
        }

        private void cleanSingleType(MessageTypes type)
        {
            if (this.data != null && this.data.ContainsKey(type))
            {
                data.Remove(type);
            }
        }
              
        private void openSingleEntryView(LogEntry entry, int columnIndex, int arrayLength)
        {
            LogEntryView lv = new LogEntryView(entry, columnIndex, arrayLength);
            lv.Show();
        }

        private Image debug = (Image)Properties.Resources._pic_debug;
        private Image debug2 = (Image)Properties.Resources._pic_debug2;
        private Image error = (Image)Properties.Resources._pic_error;
        private Image error2 = (Image)Properties.Resources._pic_error2;
        private Image fatal = (Image)Properties.Resources._pic_fatal;
        private Image fatal2 = (Image)Properties.Resources._pic_fatal2;
        private Image info = (Image)Properties.Resources._pic_info;
        private Image info2 = (Image)Properties.Resources._pic_info2;
        private Image warn = (Image)Properties.Resources._pic_warn;
        private Image warn2 = (Image)Properties.Resources._pic_warn2;

        private void changeButtonStates()
        {
            if (sets.SelectedTypes != null)
            {
                if (sets.SelectedTypes.Contains(MessageTypes.INFO.ToString()))
                {
                    btnINFO.Image = info;
                    btnINFO.BorderStyle = BorderStyle.Fixed3D;
                }
                else
                {
                    btnINFO.Image = info2;
                    btnINFO.BorderStyle = BorderStyle.None;
                }
                if (sets.SelectedTypes.Contains(MessageTypes.DEBUG.ToString()))
                {
                    btnDEBUG.Image = debug;
                    btnDEBUG.BorderStyle = BorderStyle.Fixed3D;
                }
                else
                {
                    btnDEBUG.Image = debug2;
                    btnDEBUG.BorderStyle = BorderStyle.None;
                }
                if (sets.SelectedTypes.Contains(MessageTypes.WARN.ToString()))
                {
                    btnWARN.Image = warn;
                    btnWARN.BorderStyle = BorderStyle.Fixed3D;
                }
                else
                {
                    btnWARN.Image = warn2;
                    btnWARN.BorderStyle = BorderStyle.None;
                }
                if (sets.SelectedTypes.Contains(MessageTypes.ERROR.ToString()))
                {
                    btnERROR.Image = error;
                    btnERROR.BorderStyle = BorderStyle.Fixed3D;
                }
                else
                {
                    btnERROR.Image = error2;
                    btnERROR.BorderStyle = BorderStyle.None;
                }
                if (sets.SelectedTypes.Contains(MessageTypes.FATAL.ToString()))
                {
                    btnFATAL.Image = fatal;
                    btnFATAL.BorderStyle = BorderStyle.Fixed3D;
                }
                else
                {
                    btnFATAL.Image = fatal2;
                    btnFATAL.BorderStyle = BorderStyle.None;
                }
            }
        }
        
        /// <summary>
        ///     Opens the last file if "Open last file" is activated.
        /// </summary>
        private void setLastLoadedFileDialog()
        {
            ToolStripMenuItem historyMenu = (ToolStripMenuItem)menuStripMainWindow.Items["historyToolStripMenuItem"];
            if (sets.LastOpenFile && historyMenu.DropDownItems.Count > 0)
            {
                DialogResult result = MessageBox.Show("Load the last opened log file ?\n\"" + historyMenu.DropDownItems[0].Tag + "\"",
                        "Automatic Load", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
                if (result == DialogResult.Yes)
                {
                    toolStripHistoryItem_Click(historyMenu.DropDownItems[0], null);
                }
            }
        }

        /// <summary>
        ///     Checks what types are currently active and sets this
        ///     information in the statusbar.
        /// </summary>
        private void UpdateAllEntriesInfoStatusbar()
        {
            // Count and set sum of all shown entries
            int entryLines = 0;
            StringBuilder separateTypes = new StringBuilder();
            bool firstType = true;
            int sumActive = 0;

            // This is executed for Read Methods: "Full Read", "Read Active Types"
            if (this.data != null)
            {
                foreach (MessageTypes msgType in this.data.Keys)
                {
                    List<LogEntry> logentries = this.data[msgType];
                    if (logentries != null && logentries.Count > 0)
                    {
                        if (sets.SelectedTypes.Contains(msgType.ToString()))
                        {
                            sumActive += logentries.Count;
                        }
                        entryLines += logentries.Count;
                        separateTypes.Append((firstType ? "" : " | ") + msgType.ToString() + ": " + logentries.Count);
                        firstType = false;
                    }
                }
            }

            // This is executed for Read Method: "Read Active Rows"
            else if (this.dataAccess != null && this.dataAccess.LineIndexes != null)
            {
                foreach (MessageTypes msgType in this.dataAccess.LineIndexes.Keys)
                {
                    long[] logentries = this.dataAccess.LineIndexes[msgType];
                    if (logentries != null && logentries.Length > 0)
                    {
                        if (sets.SelectedTypes.Contains(msgType.ToString()))
                        {
                            sumActive += logentries.Length;
                        }
                        entryLines += logentries.Length;
                        separateTypes.Append((firstType ? "" : " | ") + msgType.ToString() + ": " + logentries.Length);
                        firstType = false;
                    }
                }
            }

            // Nothing matches, return
            else
            {
                sumActive = 0;
            }

            this.toolStripStatusLabelCurrent.Text = sumActive.ToString();

            string sepTypes = separateTypes.Length > 0 ? "  (" + separateTypes.ToString() + ")" : "";
            this.toolStripStatusLabelAll.Text = entryLines + sepTypes;
        }

        /// <summary>
        ///     Manages the dialog "Load log file".
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OpenFileDialog()
        {
            DialogResult result = openFileDialog.ShowDialog();
            if (result.Equals(DialogResult.OK))
            {
                string filename = openFileDialog.FileName;
                bool success = LoadLogfileNew(filename);

                if (!success)
                {
                    MessageBox.Show("Cannot open logfile !", "Loading Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                }
            }
        }

     }
}